package utils

import (
	"crypto/md5"
	"datum_user/config"
	"datum_user/dao"
	"encoding/json"
	"errors"
	"fmt"
	"sort"
	"strconv"
	"time"
)

func GetVerify5Token() (string, error) {
	val, err := dao.RedisClient.Get("verify5Token").Result()
	if err != nil {
		token, err2 := getHttpVerify5Token()
		if err2 != nil {
			return "", err2
		} else {
			dao.RedisClient.Set("verify5Token", token, 24*time.Hour)
			return token, nil
		}
	} else {
		return val, nil
	}
}

func SecondVerify(verifyId string) (bool, error) {
	token, err := GetVerify5Token()
	if err != nil {
		return false, err
	}
	params := map[string]string{
		"verifyid":  verifyId,
		"timestamp": strconv.FormatInt(time.Now().UnixNano()/1e6, 10),
		"token":     token,
	}
	params["signature"] = sign(params)
	url := "https://" + config.GetString("verify5.host") + "/openapi/verify"
	//发起get请求
	resBody, err := httpGet(url, params)
	if err != nil {
		return false, err
	}
	resMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(resBody), &resMap)
	if err != nil {
		return false, err
	}
	//判断是否请求成功（成功时返回json的success）
	success, ok := resMap["success"].(bool)
	if !ok {
		return false, errors.New("verify5服务器未正确响应")
	}
	if success {
		return success, errors.New("滑动验证码二次校验成功")
	} else {
		return success, errors.New("滑动验证码二次校验失败")
	}
}

func getHttpVerify5Token() (string, error) {
	//构造get请求参数
	params := map[string]string{
		"appid":     config.GetString("verify5.app_id"),
		"timestamp": strconv.FormatInt(time.Now().UnixNano()/1e6, 10),
	}
	params["signature"] = sign(params)
	url := "https://" + config.GetString("verify5.host") + "/openapi/getToken"
	//发起get请求
	resBody, err := httpGet(url, params)
	if err != nil {
		return "", err
	}
	resMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(resBody), &resMap)
	if err != nil {
		return "", err
	}
	//判断是否请求成功（成功时返回json的success应位true）
	success, ok := resMap["success"].(bool)
	if !ok {
		return "", errors.New("verify5服务器未正确响应")
	}
	if !success {
		return "", errors.New(resMap["message"].(string))
	}
	return resMap["data"].(map[string]interface{})["token"].(string), nil
}

func sign(data map[string]string) string {
	var signStr = ""
	var strArr []string
	for k := range data {
		strArr = append(strArr, k)
	}
	sort.Strings(strArr)
	for _, k := range strArr {
		signStr += k + data[k]
	}
	signStr += config.GetString("verify5.app_key")
	return md5Encode(signStr)
}

//md5加密字符串
func md5Encode(value string) string {
	h := md5.New()
	h.Write([]byte(value))
	return fmt.Sprintf("%x", h.Sum(nil))
}
